package cn.com.easy.pay.weixinpay.controller.app;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.com.easy.dto.MessageDTO;
import cn.com.easy.exception.BusinessException;
import cn.com.easy.pay.weixinpay.config.WeixinPayConfig;
import cn.com.easy.pay.weixinpay.param.ClientToCallPayParam;
import cn.com.easy.pay.weixinpay.param.UnifiedOrderReturnParam;
import cn.com.easy.pay.weixinpay.param.UnifiedOrderUserParam;
import cn.com.easy.pay.weixinpay.utils.Signature;
import cn.com.easy.pay.weixinpay.utils.WeixinPayUnifiedOrderUtils;
import cn.com.easy.utils.ResponseOutputUtils;

/**
 * 微信统一下单基础控制器
 * 
 * @author nibili 2017年5月7日
 * 
 */
public abstract class WeixinUnifiedOrderBaseController {

	private Logger logger = LoggerFactory.getLogger(WeixinUnifiedOrderBaseController.class);

	/**
	 * 统一下单成功回调
	 * 
	 * @param request
	 * @param unifiedOrderUserParam
	 * @param unifiedOrderReturnParam
	 * @throws BusinessException
	 * @author nibili 2017年5月8日
	 */
	public abstract void successCallback(HttpServletRequest request, UnifiedOrderUserParam unifiedOrderUserParam, UnifiedOrderReturnParam unifiedOrderReturnParam)
			throws BusinessException;

	/**
	 * 获取统一下单参数
	 * 
	 * @param request
	 * @return
	 * @author nibili 2017年5月8日
	 */
	public abstract UnifiedOrderUserParam getUnifiedOrderUserParam(HttpServletRequest request) throws BusinessException;

	/**
	 * 获取微信支付配置
	 * 
	 * @param httpRequest
	 * @return
	 * @author nibili 2017年5月8日
	 */
	public abstract WeixinPayConfig getWeixinPayConfig(HttpServletRequest httpRequest) throws BusinessException;

	/**
	 * 统一下单
	 * 
	 * @param request
	 * @param response
	 * @author nibili 2017年5月7日
	 * @throws Exception
	 */
	@RequestMapping("/unifiedorder.json")
	public void unifiedorder(HttpServletRequest request, HttpServletResponse response) {
		try {
			// 微信支付配置
			WeixinPayConfig weixinPayConfig = this.getWeixinPayConfig(request);
			// 用户定义的下单参数
			UnifiedOrderUserParam unifiedOrderUserParam = this.getUnifiedOrderUserParam(request);
			// 统一下单 请求
			UnifiedOrderReturnParam unifiedOrderReturnParam = WeixinPayUnifiedOrderUtils.doUnifiedOrder(unifiedOrderUserParam, weixinPayConfig);
			// 判断下单是否成功,SUCCESS/FAIL
			if (StringUtils.equals(unifiedOrderReturnParam.getReturn_code(), "SUCCESS") == true) {

				if (StringUtils.isNotBlank(unifiedOrderReturnParam.getErr_code()) == true) {
					ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, unifiedOrderReturnParam.getErr_code_des()));
				} else {
					// 成功
					successCallback(request, unifiedOrderUserParam, unifiedOrderReturnParam);
					// 客户端发起支付的数据对象
					ClientToCallPayParam clientToCallPayParam = new ClientToCallPayParam();
					clientToCallPayParam.setAppid(unifiedOrderReturnParam.getAppid());
					// 随机字符串
					String noncestr = RandomStringUtils.random(16, true, true);
					clientToCallPayParam.setNoncestr(noncestr);
					clientToCallPayParam.setPartnerid(unifiedOrderReturnParam.getMch_id());
					clientToCallPayParam.setPrepayid(unifiedOrderReturnParam.getPrepay_id());
					long timestamp = System.currentTimeMillis() / 1000;
					clientToCallPayParam.setTimestamp(String.valueOf(timestamp));
					// 设置签名字符串
					String sign = Signature.getSign(clientToCallPayParam, weixinPayConfig.getSign_type(), weixinPayConfig.getAppkey());
					clientToCallPayParam.setSign(sign);
					//
					clientToCallPayParam.setErr_code(unifiedOrderReturnParam.getErr_code());
					clientToCallPayParam.setErr_code_des(unifiedOrderReturnParam.getErr_code_des());
					ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", true, clientToCallPayParam));
				}
			} else {
				// 错误
				ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, unifiedOrderReturnParam.getReturn_msg()));
			}
		} catch (BusinessException ex) {
			logger.error("微信统一下单发生异常(自定义异常):" + ex.getMessage(), ex);
			// 错误
			ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, ex.getMessage()));
		} catch (Exception ex) {
			logger.error("微信统一下单发生异常:" + ex.getMessage(), ex);
			// 错误
			ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, ex.getMessage()));
		}

	}

}
